#include "statisticsperspective.h"

#include "../editors/reportnavigator.h"
#include "../mainwindow.h"
#include "../utils/documentmanager.h"
#include "../utils/exportmanager.h"
#include "../utils/modelvalidator.h"

#include <coremimetypes.h>
#include <dockwidget.h>
#include <editorarea.h>
#include <iconmanager.h>
#include <mimetypemanager.h>

#include <QtCore/QSettings>
#include <QtGui/QAction>
#include <QtGui/QToolBar>

using namespace core;
using namespace gui;
using namespace swp;

StatisticsPerspective::StatisticsPerspective(PerspectiveManager* manager,
    QWidget* parent) :
        QMainWindow(parent), IPerspective(),
        m_manager(manager),
        m_reportNavigatorDock(0),
        m_reportNavigator(0),
        m_editorArea(0),
        m_exportToolBar(0),
        m_viewSeparator(0),
        m_exportAction(0)
{
    IconManager* im = IconManager::getInstance();
    im->registerStyleIcon("SwpExportReport",
        ":/swp/icons/export_report_icon.png");

    createActions();
    createCentralWidget();
    createDockWidgets();
    createToolBars();
    connectSlots();
}

StatisticsPerspective::~StatisticsPerspective()
{

}

QList<QAction* > StatisticsPerspective::getStaticActions(
    const QString& menuId) const
{
    QList<QAction* > ret;

    return ret;
}

QList<QAction* > StatisticsPerspective::getContextActions(
    const QString& menuId) const
{
    QList<QAction* > ret;

    if (menuId == VIEW_MENU)
    {
        ret.append(m_viewSeparator);
        ret.append(m_reportNavigatorDock->toggleViewAction());
    }

    return ret;
}

QList<QToolBar* > StatisticsPerspective::getStaticToolBars() const
{
    QList<QToolBar* > ret;

    return ret;
}

QList<QToolBar* > StatisticsPerspective::getContextToolBars() const
{
    QList<QToolBar* > ret;

    ret.append(m_exportToolBar);

    return ret;
}

QList<QAction* > StatisticsPerspective::getPerspectiveEnsuringActions() const
{
    QList<QAction* > ret;

    return ret;
}

IEditorArea* StatisticsPerspective::getEditorArea() const
{
    return m_editorArea;
}

bool StatisticsPerspective::canOpen(const MimeType& type) const
{
    bool ret =
        MimeTypeManager::getInstance()->mimeType(REPORT_MIMETYPE) ==
            type;

    return ret;
}

void StatisticsPerspective::handleIsCurrentChanged(bool current)
{

}

void StatisticsPerspective::readSettings(QSettings* settings)
{
    const QStringList groups = settings->childGroups();

    if (groups.contains("StatisticsPerspective"))
    {
        settings->beginGroup("StatisticsPerspective");
        restoreState(settings->value("state").toByteArray());
        settings->endGroup();
    }
}

void StatisticsPerspective::writeSettings(QSettings* settings) const
{
    settings->beginGroup("StatisticsPerspective");
    settings->setValue("state", saveState());
    settings->endGroup();
}

void StatisticsPerspective::createCentralWidget()
{
    m_editorArea = new EditorArea(this);

    setCentralWidget(m_editorArea);
}

void StatisticsPerspective::createDockWidgets()
{
    m_reportNavigator = new ReportNavigator();

    m_reportNavigatorDock = new DockWidget(
        tr("Report Navigator"), this);
    m_reportNavigatorDock->setObjectName("ReportDockWidget");
    m_reportNavigatorDock->setWidget(m_reportNavigator);
    m_reportNavigatorDock->setAllowedAreas(Qt::LeftDockWidgetArea |
        Qt::RightDockWidgetArea);
    m_reportNavigatorDock->setFeatures(
        QDockWidget::DockWidgetClosable |
        QDockWidget::DockWidgetMovable);
    m_reportNavigatorDock->setMinimumWidth(150);

    addDockWidget(Qt::LeftDockWidgetArea, m_reportNavigatorDock);
}

void StatisticsPerspective::createActions()
{
    m_viewSeparator = new QAction(this);
    m_viewSeparator->setSeparator(true);

    IconManager* im = IconManager::getInstance();

    m_exportAction = new QAction(QObject::tr("Export report"),
        this);
    m_exportAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
    m_exportAction->setEnabled(false);
    if (im->hasIcon("SwpExportReport"))
    {
        m_exportAction->setIcon(im->icon("SwpExportReport"));
    }
}

void StatisticsPerspective::createToolBars()
{
    m_exportToolBar = new QToolBar(QObject::tr("Export"), this);
    m_exportToolBar->setObjectName("ExportToolBar");

    m_reportNavigator->addToolBarActions(m_exportToolBar);

    m_exportToolBar->addAction(m_exportAction);
}

void StatisticsPerspective::connectSlots()
{
    DocumentManager* dm = DocumentManager::getInstance();

    connect(dm, SIGNAL(projectOpened(QSharedPointer<core::IDocument>)),
        m_reportNavigator, SLOT(open(QSharedPointer<core::IDocument>)));
    connect(dm, SIGNAL(projectCreated(QSharedPointer<core::IDocument>)),
        m_reportNavigator, SLOT(open(QSharedPointer<core::IDocument>)));
    connect(dm, SIGNAL(documentClosed(QSharedPointer<core::IDocument>)),
        m_reportNavigator, SLOT(close(QSharedPointer<core::IDocument>)));
    connect(dm, SIGNAL(documentAdded(
        QSharedPointer<core::IDocument>, QSharedPointer<core::IDocument>)),
            m_reportNavigator, SLOT(add(
                QSharedPointer<core::IDocument>,
                QSharedPointer<core::IDocument>)));
    connect(dm, SIGNAL(documentRemoved(
        QSharedPointer<core::IDocument>, QSharedPointer<core::IDocument>)),
            m_reportNavigator, SLOT(remove(
                QSharedPointer<core::IDocument>,
                QSharedPointer<core::IDocument>)));
    connect(dm, SIGNAL(documentRemoved(
        QSharedPointer<core::IDocument>)),
            m_reportNavigator, SLOT(remove(
                QSharedPointer<core::IDocument>)));

    connect(m_reportNavigator, SIGNAL(aboutToOpen(
        QSharedPointer<core::IDocument>)),
            dm, SLOT(openDocument(
                QSharedPointer<core::IDocument>)));
    connect(m_reportNavigator, SIGNAL(aboutToSave(
        QSharedPointer<core::IDocument>)),
            dm, SLOT(saveDocument(
                QSharedPointer<core::IDocument>)));
    connect(m_reportNavigator, SIGNAL(aboutToClose(
        QSharedPointer<core::IDocument>)),
            dm, SLOT(closeDocument(
                QSharedPointer<core::IDocument>)));
    connect(m_reportNavigator, SIGNAL(aboutToAdd(
        QSharedPointer<core::IDocument>, QList<core::MimeType>, uint, bool)),
            dm, SLOT(addDocument(
                QSharedPointer<core::IDocument>, QList<core::MimeType>, uint,
                    bool)));
    connect(m_reportNavigator, SIGNAL(aboutToRemove(
        QSharedPointer<core::IDocument>, QSharedPointer<core::IDocument>)),
            dm, SLOT(removeDocument(
                QSharedPointer<core::IDocument>,
                QSharedPointer<core::IDocument>)));
    connect(m_reportNavigator, SIGNAL(aboutToDelete(
        QSharedPointer<core::IDocument>)),
            dm, SLOT(deleteDocument(
                QSharedPointer<core::IDocument>)));

    connect(ModelValidator::getInstance(),
        SIGNAL(highlightDocumentRequest(QSharedPointer<core::IDocument>)),
        this,
        SLOT(highlightDocument(QSharedPointer<core::IDocument>)));

    MainWindow* win = MainWindow::getInstance();

    connect(m_editorArea, SIGNAL(
        currentChanged(QSharedPointer<core::IEditor>)),
            win, SLOT(
                handleEditorChange(QSharedPointer<core::IEditor>)));
    connect(m_editorArea, SIGNAL(
        currentChanged(QSharedPointer<core::IEditor>)),
            this, SLOT(
                handleEditorChange(QSharedPointer<core::IEditor>)));
    connect(m_editorArea, SIGNAL(
        aboutToClose(QSharedPointer<core::IEditor>)),
            dm, SLOT(
                closeDocument(QSharedPointer<core::IEditor>)));
    connect(dm, SIGNAL(
        documentClosed(QSharedPointer<core::IEditor>)),
            m_editorArea, SLOT(
                confirmClose(QSharedPointer<core::IEditor>)));
    connect(m_editorArea, SIGNAL(aboutToSave(
        QSharedPointer<core::IDocument>)), dm, SLOT(
            saveDocument(QSharedPointer<core::IDocument>)));

    connect(m_exportAction, SIGNAL(triggered()),
        this, SLOT(exportReport()));

    win->registerForSaveNotification(this, m_editorArea);
    win->registerForSaveNotification(this, m_reportNavigator);
}

// private slots
void StatisticsPerspective::handleEditorChange(
    const QSharedPointer<IEditor>& editor)
{
    m_exportAction->setEnabled(!editor.isNull());
}

void StatisticsPerspective::highlightDocument(
    const QSharedPointer<IDocument>& document)
{
    m_reportNavigator->tryToSelectDocument(document);

    if (!document->isFuture() && canOpen(document->mimeType()))
    {
        if (m_manager != 0)
        {
            m_manager->ensurePerspectiveRequest(this);
        }

        m_editorArea->openEditor(document);
    }
}

void StatisticsPerspective::exportReport()
{
    if (m_editorArea->currentEditor() != 0)
    {
        ExportManager::getInstance()->exportReport(
            m_editorArea->currentEditor()->document());
    }
}
